
package com.dlc.shop.delivery.common.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dlc.shop.bean.app.dto.DeliveryDto;
import com.dlc.shop.bean.app.dto.DeliveryInfoDto;
import com.dlc.shop.bean.enums.*;
import com.dlc.shop.bean.model.*;
import com.dlc.shop.common.enums.StatusEnum;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.util.BeanUtil;
import com.dlc.shop.common.util.Json;
import com.dlc.shop.config.WxConfig;
import com.dlc.shop.dao.OrderItemMapper;
import com.dlc.shop.delivery.common.dao.ChinaDeliveryOrderItemMapper;
import com.dlc.shop.delivery.common.dao.ChinaDeliveryOrderMapper;
import com.dlc.shop.delivery.common.manager.DeliveryPrintManager;
import com.dlc.shop.delivery.common.model.ChinaDeliveryOrder;
import com.dlc.shop.delivery.common.model.ChinaDeliveryOrderItem;
import com.dlc.shop.delivery.common.model.DeliveryOrder;
import com.dlc.shop.delivery.common.param.DeliveryOrderItemParam;
import com.dlc.shop.delivery.common.param.OrderItemParam;
import com.dlc.shop.delivery.common.service.ChinaDeliveryOrderItemService;
import com.dlc.shop.delivery.common.service.ChinaDeliveryOrderService;
import com.dlc.shop.service.*;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 国内物流发货-订单物流
 * @author liyong
 */
@Service
@AllArgsConstructor
public class ChinaDeliveryOrderServiceImpl extends ServiceImpl<ChinaDeliveryOrderMapper, ChinaDeliveryOrder> implements ChinaDeliveryOrderService {

    private final ChinaDeliveryOrderMapper chinaDeliveryOrderMapper;

    private final ChinaDeliveryOrderItemMapper chinaDeliveryOrderItemMapper;

    private final ChinaDeliveryOrderItemService chinaDeliveryOrderItemService;
    private final OrderService orderService;
    private final NotifyTemplateService notifyTemplateService;
    private final DeliveryService deliveryService;
    private final OrderRefundService orderRefundService;
    private final OrderItemMapper orderItemMapper;
    private final WxConfig wxConfig;
    private final PayInfoService payInfoService;
    private final DeliveryPrintManager deliveryPrintManager;
    private final ShopDetailService shopDetailService;
    /**
     * 生成物流信息及保存物流与订单关联
     * @param deliveryOrderParam 物流信息
     * @param shopId 店铺id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDeliveriesInfo(DeliveryOrderItemParam deliveryOrderParam, Long shopId) {
        List<OrderItem> selectOrderItems = deliveryOrderParam.getSelectOrderItems();
        for (OrderItem selectOrderItem : selectOrderItems) {
            if (Objects.equals(selectOrderItem.getDvyType(), DvyType.DELIVERY.value())) {
                selectOrderItem.setDvyType(DvyType.DELIVERY.value());
            } else {
                selectOrderItem.setDvyType(deliveryOrderParam.getDeliveryType());
            }
        }
        String orderNumber = deliveryOrderParam.getOrderNumber();
        Order order = orderService.getOrderAndOrderItemByOrderNumber(orderNumber);
        if(!Objects.equals(order.getShopId(),shopId)){
            // 订单不存在
            throw new YamiShopBindException("yami.order.no.exist");
        }
        deliveryOrderParam.setReceiverMobile(order.getReceiverMobile());
        deliveryOrderParam.setReceiverName(order.getReceiverName());
        deliveryOrderParam.setAddrOrderId(order.getAddrOrderId());
        boolean isSend = Objects.equals(deliveryOrderParam.getDeliveryType(),DvyType.DELIVERY.value()) ||
                Objects.equals(deliveryOrderParam.getDeliveryType(), DvyType.ONLINE.value()) ||
                Objects.equals(deliveryOrderParam.getDeliveryType(),DvyType.NOT_DELIVERY.value()) ||
                Objects.equals(deliveryOrderParam.getDeliveryType(),DvyType.SAME_CITY.value());
        ChinaDeliveryOrder deliveryOrder = checkIsSend(deliveryOrderParam, selectOrderItems, order, isSend);

        //修改为发货状态 指定字段信息 标记
        order.setStatus(OrderStatus.SENDWAREHOUSE.value());
        order.setIsChinaDvy(1);
        orderService.updateById(order);
    }



    private ChinaDeliveryOrder checkIsSend(DeliveryOrderItemParam deliveryOrderParam, List<OrderItem> selectOrderItems, Order order, boolean isSend) {
        ChinaDeliveryOrder deliveryOrder = new ChinaDeliveryOrder();
        deliveryOrder.setProductNums(0);
        if (isSend){
            //校验订单状态，发货数量及获取发货的总数
            int prodNumSum = checkDelivery(order, selectOrderItems);
            deliveryOrder.setOrderNumber(deliveryOrderParam.getOrderNumber());
            if (Objects.equals(deliveryOrderParam.getDeliveryType(),DvyType.DELIVERY.value())){
                deliveryOrder.setDvyId(deliveryOrderParam.getDvyId());
                deliveryOrder.setDvyFlowId(deliveryOrderParam.getDvyFlowId());
            }
            deliveryOrder.setCreateTime(new Date());
            deliveryOrder.setUpdateTime(new Date());
            deliveryOrder.setStatus(1);
            deliveryOrder.setReceiverMobile(order.getReceiverMobile());
            deliveryOrder.setProductNums(prodNumSum);
            deliveryOrder.setDeliveryType(deliveryOrderParam.getDeliveryType());
            deliveryOrder.setPlatformAddr(Json.toJsonString(deliveryOrderParam.getPlatformAddr()));
            //保存订单物流信息
            save(deliveryOrder);
            //保存需要添加的关联信息
            List<ChinaDeliveryOrderItem> addDeliveries = new ArrayList<>();
            for (OrderItem selectOrderItem : selectOrderItems) {
                ChinaDeliveryOrderItem deliveryOrderItem = new ChinaDeliveryOrderItem();
                deliveryOrderItem.setOrderItemId(selectOrderItem.getOrderItemId());
                deliveryOrderItem.setProdCount(selectOrderItem.getChangeNum());
                deliveryOrderItem.setOrderDeliveryId(deliveryOrder.getOrderDeliveryId());
                addDeliveries.add(deliveryOrderItem);
            }
            if(CollectionUtils.isNotEmpty(addDeliveries)){
                chinaDeliveryOrderItemService.saveBatch(addDeliveries);
            }
        }
        return deliveryOrder;
    }
    private boolean checkDeliveryComplete(String orderNumber, Order order) {
        boolean isDelivery = true;
        List<OrderItem> orderItems;
        // 处理一下组合商品的发货
        if(order.getOrderItems().stream().filter(orderItem -> Objects.equals(orderItem.getMold(), ProdMoldEnum.COMBO.value())).count() > 0){
            orderItems = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderNumber, orderNumber));
            Map<Long, List<OrderItem>> childComboItems = orderItems.stream().filter(orderItem -> Objects.equals(orderItem.getActivityType(), OrderActivityType.COMBO_PROD.value()) && !Objects.equals(orderItem.getStatus(),-1))
                    .collect(Collectors.groupingBy(OrderItem::getActivityId));
            List<OrderItem> updateOrderItems = new ArrayList<>();
            for (Long mainItemId : childComboItems.keySet()) {
                // 检查下是否所有的子组合项都发货了
                List<OrderItem> items = childComboItems.get(mainItemId);
                long unDeliveryCount = items.stream().filter(orderItem -> !Objects.equals(orderItem.getStatus(), 0)).count();
                if(unDeliveryCount == 0){
                    long count = items.stream().filter(orderItem -> Objects.equals(orderItem.getDvyType(), DvyType.DELIVERY.value())).count();
                    OrderItem orderItem = new OrderItem();
                    orderItem.setOrderItemId(mainItemId);
                    orderItem.setStatus(0);
                    // 如果有一个快递发货的方式,那就是快递发货,否则就是第一个的发货方式,因为如果是自提/同城配送/无需快递那就都是这三
                    orderItem.setDvyType(count > 0 ? DvyType.DELIVERY.value() : items.get(0).getDvyType());
                    orderItemMapper.updateById(orderItem);
                }
            }
        }
        if (Objects.isNull(order.getRefundStatus())){
            orderItems = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderNumber, orderNumber));
        }else {
            orderItems = orderItemMapper.getListByOrderNumber(orderNumber);
            List<Long> orderItemIds = orderItems.stream().map(OrderItem::getOrderItemId).toList();
            orderItems.removeIf(orderItem -> Objects.equals(orderItem.getActivityType(),OrderActivityType.GIVEAWAY.value()) && !orderItemIds.contains(orderItem.getActivityId()));
            orderItems.removeIf(orderItem -> Objects.equals(orderItem.getActivityType(),OrderActivityType.COMBO_PROD.value()));
        }
        // 有多个商品的订单，有退款记录的，并且有退款成功的单个商品，
        // 其余的商品都是发货完成的订单，改成发货状态
        // 在退款处理的时候将状态改为0即可
        for (OrderItem orderItem : orderItems) {
            if (orderItem.getStatus() != 0) {
                isDelivery = false;
                break;
            }
        }
        List<ChinaDeliveryOrder> deliveryOrders = listDetailDelivery(orderNumber);
        if (deliveryOrders.size() >= 10 && !isDelivery) {
            throw new YamiShopBindException("yami.order.deliver.size.exist");
        }
        return isDelivery;
    }

    @Override
    public List<ChinaDeliveryOrder> listDetailDelivery(String orderNumber) {
        return chinaDeliveryOrderMapper.listDetailDelivery(orderNumber);
    }

    /**
     * 修改物流信息
     * @param deliveryOrders 物流修改的信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderDeliveries(List<DeliveryOrder> deliveryOrders) {
        //updateWechatPayDelivery(deliveryOrders);
        List<ChinaDeliveryOrder> list = new ArrayList<>();
        for (DeliveryOrder deliveryOrder : deliveryOrders) {
            ChinaDeliveryOrder chinaDeliveryOrder = BeanUtil.map(deliveryOrder, ChinaDeliveryOrder.class);
            list.add(chinaDeliveryOrder);
        }
        list.forEach(deliveryOrder-> deliveryOrder.setUpdateTime(new Date()));
        updateBatchById(list);
    }


    @Override
    public ChinaDeliveryOrder deliveryOrderItemInfo(Long orderDeliveryId) {
        List<ChinaDeliveryOrder> deliveryOrders = chinaDeliveryOrderMapper.getAndDeliveryItemInfo(null, orderDeliveryId);
        for (ChinaDeliveryOrder deliveryOrder : deliveryOrders) {
            for (OrderItemParam orderItem : deliveryOrder.getOrderItems()) {
                orderItem.setOrderType(deliveryOrder.getOrderType());
                if (Objects.equals(orderItem.getActivityType(),OrderActivityType.GIVEAWAY.value())){
                    orderItem.setType(1);
                }

                if (!Objects.equals(orderItem.getPreSellStatus(), StatusEnum.ENABLE.value())){
                    orderItem.setPreSaleTime(null);
                }
            }
        }
        if (CollUtil.isEmpty(deliveryOrders)) {
            return new ChinaDeliveryOrder();
        }
        ChinaDeliveryOrder deliveryOrder = deliveryOrders.get(0);
        if (Objects.nonNull(deliveryOrder) && Objects.nonNull(deliveryOrder.getDvyId())){
            // 查询交易单
            DeliveryDto deliveryDto = getDelivery(deliveryOrder);
            deliveryOrder.setDeliveryDto(deliveryDto);
            if(Objects.nonNull(deliveryOrder.getDeliveryDto()) && CollectionUtils.isNotEmpty(deliveryOrder.getDeliveryDto().getTraces())){
                Collections.reverse(deliveryOrder.getDeliveryDto().getTraces());
            }
        }
        // 处理下相同的sku信息集合
        Map<Long, List<OrderItemParam>> itemMap = deliveryOrder.getOrderItems().stream().collect(Collectors.groupingBy(OrderItemParam::getSkuId));
        List<OrderItemParam> orderItemParams = new ArrayList<>();
        for (Long skuId : itemMap.keySet()) {
            int sum = itemMap.get(skuId).stream().mapToInt(OrderItemParam::getProdCount).sum();
            OrderItemParam orderItemParam = itemMap.get(skuId).get(0);
            orderItemParam.setProdCount(sum);
            orderItemParams.add(orderItemParam);
        }
        deliveryOrder.setOrderItems(orderItemParams);
        return deliveryOrder;
    }



    @Override
    public List<ChinaDeliveryOrder> getAndDeliveryItemInfo(String orderNumber) {
        List<ChinaDeliveryOrder> deliveryOrders = chinaDeliveryOrderMapper.getAndDeliveryItemInfo(orderNumber, null);
        if (CollUtil.isEmpty(deliveryOrders)) {
            return new ArrayList<>();
        }
        // 查询物流详情信息
        // 物流公司名称、官网、订单号、物流详情信息
        ChinaDeliveryOrder deliveryOrder = deliveryOrders.get(0);
        if (Objects.nonNull(deliveryOrder.getDvyId())){
            // 查询交易单
            DeliveryDto deliveryDto = getDelivery(deliveryOrder);
            deliveryOrder.setDeliveryDto(deliveryDto);
            if(Objects.nonNull(deliveryOrder.getDeliveryDto()) && CollectionUtils.isNotEmpty(deliveryOrder.getDeliveryDto().getTraces())){
                // 按照时间正序排列返回给前端
                List<DeliveryInfoDto> deliveryInfoList = deliveryOrder.getDeliveryDto().getTraces().stream().sorted(Comparator.comparing(DeliveryInfoDto::getAcceptTime)).toList();
                deliveryOrder.getDeliveryDto().setTraces(deliveryInfoList);
            }
        }
        for (ChinaDeliveryOrder order : deliveryOrders) {
            Map<Long, List<OrderItemParam>> itemMap = order.getOrderItems().stream().collect(Collectors.groupingBy(OrderItemParam::getOrderItemId));
            List<OrderItemParam> orderItemParams = new ArrayList<>();
            for (Long orderItemId : itemMap.keySet()) {
                int sum = itemMap.get(orderItemId).stream().mapToInt(OrderItemParam::getProdCount).sum();
                OrderItemParam orderItemParam = itemMap.get(orderItemId).get(0);
                orderItemParam.setProdCount(sum);
                orderItemParams.add(orderItemParam);
            }
            // 根据订单项id排序
            orderItemParams = orderItemParams.stream().sorted(Comparator.comparing(OrderItemParam::getOrderItemId)).collect(Collectors.toList());
            order.setOrderItems(orderItemParams);
            for (OrderItemParam orderItem : deliveryOrder.getOrderItems()) {
                orderItem.setOrderType(deliveryOrder.getOrderType());
                if (Objects.equals(orderItem.getActivityType(),OrderActivityType.GIVEAWAY.value())){
                    orderItem.setType(1);
                }
            }
        }
        return deliveryOrders;
    }


    private DeliveryDto getDelivery(ChinaDeliveryOrder deliveryOrder){

        DeliveryDto deliveryDto;
        try {
            Delivery delivery = new Delivery();
            if (Objects.equals(deliveryOrder.getDeliveryType(), DeliveryType.EXPRESS.getValue())) {
                delivery = deliveryService.getById(deliveryOrder.getDvyId());
            } else if (Objects.equals(deliveryOrder.getDeliveryType(), DeliveryType.ONLINE.getValue())){
                delivery = DeliveryCompanyType.getByDeliveryCompanyType(deliveryOrder.getDvyId());
            }
            // 解析的物流详情明细
            deliveryDto = deliveryService.query(delivery, deliveryOrder.getDvyFlowId(), deliveryOrder.getReceiverMobile());
            deliveryDto.setCompanyHomeUrl(delivery.getCompanyHomeUrl());
            deliveryDto.setCompanyName(delivery.getDvyName());
            deliveryDto.setDvyFlowId(deliveryOrder.getDvyFlowId());
        } catch (Exception e) {
            log.error("物流查询错误：", e);
            // 查询出错
            throw new YamiShopBindException("yami.query.error");
        }
        return deliveryDto;
    }
    /**
     * 校验可发货数量并返回总数
     * @param order 订单信息
     * @param selectOrderItems 选择发货的订单项
     */
    private int checkDelivery(Order order, List<OrderItem> selectOrderItems) {
       //if (!Objects.equals(order.getStatus(), OrderStatus.PADYED.value()) && Objects.equals(order.getDvyType(), DvyType.STATION.value())) {
       //    // 订单不处于待入库状态，无法进行入库
       //    throw new YamiShopBindException("yami.order.status.no.right");
       //} else if (!Objects.equals(order.getStatus(), OrderStatus.PADYED.value())) {
       //    // 订单不处于待发货状态，无法进行发货
       //    throw new YamiShopBindException("yami.order.delivery.no.right");
       //}
        List<OrderRefund> orderRefunds = orderRefundService.getProcessingOrderRefundByOrderId(order.getOrderId());
        // 移除退款成功的退款记录
        orderRefunds.removeIf(orderRefund -> orderRefund.getReturnMoneySts() == 5);
        if (CollectionUtil.isNotEmpty(orderRefunds)) {
            // 该订单有退款信息正在处理当中，请处理完毕之后再进行发货的操作!
            throw new YamiShopBindException("yami.order.delivery.refund.error");
        }
        Map<Long, OrderItem> itemMap = order.getOrderItems().stream().collect(Collectors.toMap(OrderItem::getOrderItemId, orderItem -> orderItem));
        //获取发货总数
        int prodNumSum = 0;
        for (OrderItem selectOrderItem : selectOrderItems) {
            prodNumSum += selectOrderItem.getChangeNum();
            if(!itemMap.containsKey(selectOrderItem.getOrderItemId())){
                // 订单不存在
                throw new YamiShopBindException("yami.order.no.exist");
            }
            OrderItem orderItemDb = itemMap.get(selectOrderItem.getOrderItemId());
            // 这里把数据库查询到的数量放进去，以免前端传了错误的数量
            selectOrderItem.setProdCount(Objects.equals(orderItemDb.getStatus(),-1) ? orderItemDb.getProdCount() : orderItemDb.getStatus());
            if(!Objects.equals(orderItemDb.getStatus(),-1) && orderItemDb.getStatus() < selectOrderItem.getChangeNum()){
                // 订单发货数量不足，请刷新后再试
                throw new YamiShopBindException("yami.order.delivery.num.check");
            }
        }
        return prodNumSum;
    }
}
